<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>DeepSpeech reports</title>

    <link rel="stylesheet" href="resources/bootstrap.min.css" />
    <link rel="stylesheet" href="resources/jquery-ui.min.css" />
    <link rel="stylesheet" href="resources/rickshaw.min.css" />

    <script src="resources/jquery-3.1.1.min.js"></script>
    <script src="resources/jquery-ui.min.js"></script>
    <script src="resources/d3.v3.min.js"></script>
    <script src="resources/rickshaw.min.js"></script>

    <script type="text/javascript">
        window.ALL_THE_DATA = [];
        window.logwer = function(hash, time, type, wer) {
            window.ALL_THE_DATA.push({ hash: hash, time: time, type: type, wer: wer });
        };
    </script>

    <script src="werlog.js"></script>

    <style type="text/css">
        .rickshaw_legend {
            color: black;
            background: transparent;
        }
        .rickshaw_legend .line {
            display: inline;
        }
    </style>
</head>
<body>

    <div id="panels" class="container"></div>

    <script src="resources/bootstrap.min.js"></script>

    <script type="text/javascript">

        const createChart = (id, title, fineprint, series, times) => {

            var panelRoot = $('#panels');

            var panel = $('<div/>').attr('id', id); panelRoot.append(panel);

            panel.append('<h1>' + title + '</h1>');
            panel.append('<p>' + fineprint + '</p>');

            var cContainer = $('<div/>'); panel.append(cContainer);
            var cChart =     $('<div/>'); cContainer.append(cChart);
            var cPreview =   $('<div/>'); cContainer.append(cPreview);
            var cTimeline =  $('<div/>'); cContainer.append(cTimeline);
            var cLegend =    $('<div/>'); cContainer.append(cLegend);

            var graph = new Rickshaw.Graph({
                element: cChart[0],
                height: 500,
                renderer: 'area',
                interpolation: 'linear',
                unstack: 'true',
                stroke: true,
                preserve: true,
                series: series
            });

            graph.render();

            var preview = new Rickshaw.Graph.RangeSlider({
                graph: graph,
                element: cPreview[0]
            });

            var hoverDetail = new Rickshaw.Graph.HoverDetail({
                graph: graph,
                xFormatter: function(x) {
                    if (times)
                        return new Date(x * 1000.0).toString();
                    else
                        return x;
                },
                yFormatter: function(y) {
                    return (y * 100).toFixed(2) + '%';
                }
            });

            var legend = new Rickshaw.Graph.Legend({
                graph: graph,
                element: cLegend[0]
            });

            var shelving = new Rickshaw.Graph.Behavior.Series.Toggle({
                graph: graph,
                legend: legend
            });

            var order = new Rickshaw.Graph.Behavior.Series.Order({
                graph: graph,
                legend: legend
            });

            var highlighter = new Rickshaw.Graph.Behavior.Series.Highlight({
                graph: graph,
                legend: legend
            });

            var ticksTreatment = 'glow';

            if (times) {
                var xAxis = new Rickshaw.Graph.Axis.Time({
                    graph: graph,
                    ticksTreatment: ticksTreatment,
                    timeFixture: new Rickshaw.Fixtures.Time.Local()
                });

                var annotator = new Rickshaw.Graph.Annotate({
                    graph: graph,
                    element: cTimeline[0]
                });

                times.forEach(time => annotator.add(time, new Date(time * 1000.0).toString()));
                annotator.update();

                xAxis.render();
            }

            var yAxis = new Rickshaw.Graph.Axis.Y({
                graph: graph,
                tickFormat: function(y) { return (y * 100).toFixed(0) + '%'; },
                ticksTreatment: ticksTreatment
            });

            yAxis.render();

        };

        var ds = window.ALL_THE_DATA,
            i,
            reports  = {},
            overall_test_wer = [],
            overall_validation_wer = [],
            overall_train_wer = [],
            times = [];

        ds.forEach(item => {
            var time = new Date(item.time).getTime() / 1000.0;
            if (item.type == 'train')
                overall_train_wer.push({ x: time, y: item.wer });
            else if (item.type == 'dev')
                overall_validation_wer.push({ x: time, y: item.wer });
            else
                overall_test_wer.push({ x: time, y: item.wer });
            times.push(time);
        });

        const stdtext =
            'The Y axis plots the mean word error rate ' +
            '<a href="https://en.wikipedia.org/wiki/Word_error_rate">WER</a> ' +
            '(of the training\'s last epoch).' +
            '<p>Lower is better: 0% WER equates to "all words were understood correctly", ' +
            'while 100% WER equates to "every single word was wrong". ' +
            'Percentages greater than 100% may occur, if the "understood" phrase got longer than the original one.</p><p>' +
            '<strong>Train WER</strong>, <strong>Train WER</strong> and <strong>Train WER</strong> ' +
            'refer to the WERs calculated on base of the corresponding ' +
            '<a href="https://en.wikipedia.org/wiki/Test_set#Validation_set">data-sets.</a></p><p>' +
            'Please use the legend for turning on/off data series.</p>';

        var groups = [];
        if (overall_validation_wer.length > 0)
            groups.push({ color: 'rgba(100,100,255,0.5)', data: overall_validation_wer, name: 'Validate WER' });
        if (overall_train_wer.length > 0)
            groups.push({ color: 'rgba(255,100,100,0.5)', data: overall_train_wer, name: 'Train WER' });
        if (overall_test_wer.length > 0)
            groups.push({ color: 'rgba(100,255,100,0.5)', data: overall_test_wer, name: 'Test WER' });

        createChart(
            'overall_wer',
            'DeepSpeech Word Error Rate over time',
            'The X axis plots all trainings by their start times. ' + stdtext,
            groups,
            times
        );
    </script>

</body>
</html>
